package com.snail.clouds.storage.providers.tianyi_tv;

import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.crypto.digest.HMac;
import cn.hutool.crypto.digest.HmacAlgorithm;
import cn.hutool.core.date.DateUtil;

import java.util.HashMap;
import java.util.Map;
import java.util.Date;
import java.util.TimeZone;
import java.text.SimpleDateFormat;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 天翼TV工具类
 * 提供签名、加密等工具方法
 */
public class SignatureUtils {
    
    // 常量定义，参考Go实现
    public static final String TV_APP_KEY = "600100885";
    public static final String TV_APP_SIGNATURE_SECRET = "fe5734c74c2f96a38157f420b32dc995";
    public static final String TV_VERSION = "6.5.5";
    public static final String ANDROID_TV = "FAMILY_TV";
    public static final String TV_CHANNEL_ID = "home02";
    public static final String API_URL = "https://api.cloud.189.cn";
    
    /**
     * 获取客户端后缀参数
     * 参考Go实现：clientSuffix()
     */
    public static Map<String, Object> getClientSuffix() {
        Map<String, Object> params = new HashMap<>();
        params.put("clientType", ANDROID_TV);
        params.put("version", TV_VERSION);
        params.put("channelId", TV_CHANNEL_ID);
        params.put("clientSn", "unknown");
        params.put("model", "PJX110");
        params.put("osFamily", "Android");
        params.put("osVersion", "35");
        params.put("networkAccessMode", "WIFI");
        params.put("telecomsOperator", "46011");
        return params;
    }
    
    /**
     * 生成AppKey签名头
     * 参考Go实现：AppKeySignatureHeader
     */
    public static Map<String, String> getAppKeySignatureHeader(String url, String method) {
        // 使用毫秒时间戳，与Go实现一致
        long timestamp = System.currentTimeMillis();
        
        // 生成签名
        String signature = appKeySignatureOfHmac(
                TV_APP_SIGNATURE_SECRET,
                TV_APP_KEY,
                method,
                url,
                timestamp
        );
        
        Map<String, String> headers = new HashMap<>();
        // 返回数据格式为 json
        headers.put("Accept", "application/json");
        headers.put("Content-Type", "application/json");
        headers.put("Timestamp", String.valueOf(timestamp));
        headers.put("X-Request-ID", IdUtil.randomUUID());
        headers.put("AppKey", TV_APP_KEY);
        headers.put("AppSignature", signature);
        return headers;
    }
    
    /**
     * 生成SessionKey签名头
     * 参考Go实现：SignatureHeader
     */
    public static Map<String, String> getSignatureHeader(String url, String method,
                                                         String sessionKey, String sessionSecret) {
        String dateStr = getHttpDateStr();
        
        // 生成签名
        String signature = sessionKeySignatureOfHmac(
                sessionSecret,
                sessionKey,
                method,
                url,
                dateStr
        );
        
        Map<String, String> headers = new HashMap<>();
        headers.put("Date", dateStr);
        headers.put("SessionKey", sessionKey);
        headers.put("X-Request-ID", IdUtil.randomUUID());
        headers.put("Signature", signature);
        return headers;
    }
    
    /**
     * 生成AppKey HMAC签名
     * 参考Go实现：AppKeySignatureOfHmac
     */
    public static String appKeySignatureOfHmac(String secret, String appKey, String method, String url, long timestamp) {
        // 提取URL路径，与Go实现一致
        String urlpath = extractUrlPath(url);
        
        // 构建签名字符串，与Go实现一致
        String signString = "AppKey=" + appKey + "&Operate=" + method + "&RequestURI=" + urlpath + "&Timestamp=" + timestamp;
        
        // 生成HMAC签名
        HMac hmac = new HMac(HmacAlgorithm.HmacSHA1, secret.getBytes());
        byte[] signatureBytes = hmac.digest(signString);
        
        StringBuilder sb = new StringBuilder();
        for (byte b : signatureBytes) {
            sb.append(String.format("%02X", b));
        }
        return sb.toString();
    }
    
    /**
     * 生成SessionKey HMAC签名
     * 参考Go实现：SessionKeySignatureOfHmac
     */
    public static String sessionKeySignatureOfHmac(String secret, String sessionKey, String method, String url, String date) {
        // 提取URL路径，与Go实现一致
        String urlpath = extractUrlPath(url);
        
        // 构建签名字符串，与Go实现一致
        String signString = "SessionKey=" + sessionKey + "&Operate=" + method + "&RequestURI=" + urlpath + "&Date=" + date;
        
        // 生成HMAC签名
        HMac hmac = new HMac(HmacAlgorithm.HmacSHA1, secret.getBytes());
        byte[] signatureBytes = hmac.digest(signString);
        
        StringBuilder sb = new StringBuilder();
        for (byte b : signatureBytes) {
            sb.append(String.format("%02X", b));
        }
        return sb.toString();
    }
    
    /**
     * 提取URL路径
     * 参考Go实现中的正则表达式
     */
    private static String extractUrlPath(String url) {
        Pattern pattern = Pattern.compile("://[^/]+((/[^/\\s?#]+)*)");
        Matcher matcher = pattern.matcher(url);
        if (matcher.find()) {
            return matcher.group(1);
        }
        return "";
    }
    
    /**
     * 获取HTTP日期字符串
     * 参考Go实现：getHttpDateStr
     */
    public static String getHttpDateStr() {
        SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US);
        sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
        return sdf.format(new Date());
    }
    
    /**
     * 获取时间戳（毫秒）
     * 参考Go实现：timestamp
     */
    public static long getTimestamp() {
        return System.currentTimeMillis();
    }
    
    /**
     * 转换家庭云排序方式
     * 参考Go实现：toFamilyOrderBy
     */
    public static String toFamilyOrderBy(String orderBy) {
        switch (orderBy) {
            case "filename":
                return "1";
            case "filesize":
                return "2";
            case "lastOpTime":
                return "3";
            default:
                return "1";
        }
    }
    
    /**
     * 转换排序方向
     * 参考Go实现：toDesc
     */
    public static String toDesc(String orderDirection) {
        switch (orderDirection) {
            case "desc":
                return "true";
            case "asc":
            default:
                return "false";
        }
    }
    
    /**
     * 布尔值转数字
     * 参考Go实现：BoolToNumber
     */
    public static int boolToNumber(boolean b) {
        return b ? 1 : 0;
    }
    
    /**
     * 解析时间字符串
     * 参考Go实现中的Time.Unmarshal方法
     */
    public static Date parseTimeString(String timeStr) {
        if (StrUtil.isBlank(timeStr)) {
            return null;
        }
        
        try {
            // 尝试多种时间格式
            String[] formats = {
                "yyyy-MM-dd HH:mm:ss Z",
                "MMM d, yyyy HH:mm:ss a Z",
                "yyyy-MM-dd HH:mm:ss",
                "yyyy-MM-dd'T'HH:mm:ss",
                "yyyy-MM-dd'T'HH:mm:ssZ"
            };
            
            for (String format : formats) {
                try {
                    return DateUtil.parse(timeStr, format);
                } catch (Exception e) {
                    // 继续尝试下一个格式
                }
            }
            
            // 尝试解析为时间戳
            return new Date(Long.parseLong(timeStr));
        } catch (Exception e) {
            return null;
        }
    }
}
